/*
 * Hardware.h
 *
 *  Created on: 22/05/2013
 *      Author: roger
 */

#ifndef HARDWARE_H_
#define HARDWARE_H_
#include <LSM303.h>
#include <Adafruit_GFX.h>
#include <Adafruit_TFTLCD.h>
#include <TouchScreen.h>
#include <SD.h>
#include <Wire.h>
#include <Time.h>
#include <LowPower_Teensy3.h>
#include "HeartRateInterrupt.h"

//#define HARDWARE_DEBUG
#define SD_CS 10
#define BACKLIGHT 26
#define CTS 25
extern Adafruit_TFTLCD Graphics;

// Assign human-readable names to some common 16-bit color values:
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A9 // Chip Select goes to Analog 3
#define LCD_CD A3 // Command/Data goes to Analog 2
#define LCD_WR A2 // LCD Write goes to Analog 1
#define LCD_RD A1 // LCD Read goes to Analog 0
#define LCD_RESET A8 // Can alternately just connect to Arduino's reset pin

#define YM 4   // can be a digital pin
#define XM A3  // must be an analog pin, use "An" notation!
#define YP A9  // must be an analog pin, use "An" notation!
#define XP 3   // can be a digital pin

#define TS_MINX 105
#define TS_MINY 223
#define TS_MAXX 914
#define TS_MAXY 995

#define PENRADIUS 3
#define MINPRESSURE 5
#define MAXPRESSURE 1000

#define TONE_PIN 9
#define LED0_PIN 27
#define LED1_PIN 28

#define VOLTAGE_PIN 11
#define PULSE_PIN 10
#define POWER_PIN 24

#define HEADER_PIXEL(data,pixel) {\
pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \
pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \
pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \
data += 4; \
}

class Icon {
public:
	unsigned int size;
	const char *bitmap;
	Icon(const unsigned int s, const char *data) {
		size = s;
		bitmap = data;
	};
	virtual ~Icon() {
	};
	const void draw(const int x, const int y) {
		const char *pImg = bitmap;

		char pRGB[3];
		for (unsigned int j = 0; j < size; j++) {

			for (unsigned int i = 0; i < size; i++) {
				pRGB[0] = (((pImg[0] - 33) << 2) | ((pImg[1] - 33) >> 4));
				pRGB[1] = ((((pImg[1] - 33) & 0xF) << 4) | ((pImg[2] - 33) >> 2));
				pRGB[2] = ((((pImg[2] - 33) & 0x3) << 6) | ((pImg[3] - 33)));
				pImg += 4;
				uint16_t colour = ((unsigned long) pRGB[0])
						+ (((unsigned long) pRGB[1]) << 8)
						+ (((unsigned long) pRGB[2]) << 16);
				Graphics.drawPixel(x + i, y + j, colour);
			}
		}
	}
};

class Hardware_ {
private:
	LSM303 m_lsm303;
	char dstring[20];
	bool m_sdOK=false;
	TEENSY3_LP m_lowPower;

public:
	Hardware_();
	void init();
	void shutdown();
	int compassHeading();
	void compass(bool start);
	void blink0() {
		digitalWrite(LED0_PIN, HIGH);
		delay(50);
		digitalWrite(LED0_PIN, LOW);
	}
	void blink1() {
		digitalWrite(LED1_PIN, HIGH);
		delay(50);
		digitalWrite(LED1_PIN, LOW);
	}
	LSM303::vector getAccelerometerValues();
	bool isSDOK() { return m_sdOK;};
	const char *timeString(long adjustedDate);
	const char *dateString(long adjustedDate);
	void progmemPrint(const char *str);
	void progmemPrintln(const char *str);
//	void drawIcon(const int x, const int y, const Icon *icon);
//	void drawIcon(const unsigned int size,const int x, const int y, const char *pImg);
	void printDirectory(File dir, int numTabs);
	int readInt(File dataFile);
	float getBatteryVoltage();
	void playTone(uint16_t frequency, uint32_t duration = 0, uint32_t delay_after = 40);
	void siren();
	void dumpSD(const char *message) {
		Serial.print(PSTR("dumpSD "));
		Serial.println(message);
		File root = SD.open("/");
		printDirectory(root, 0);
		root.close();
		Serial.print(PSTR("dumpSD done ("));
		Serial.print(message);
		Serial.println(")");
	}
	uint16_t read16(File f);
	uint32_t read32(File f);
	virtual ~Hardware_();
};

extern Hardware_ Hardware;
extern TouchScreen Touchscreen;
extern Adafruit_TFTLCD Graphics;


#endif /* HARDWARE_H_ */
